const Router = require('koa-router');
const glob = require('glob');
const _ = require('lodash');
const { resolve } = require('path');
const symbolPrefix = Symbol('prefix');
const routerMap = new Map();

const isArray = c => _.isArray(c) ? c : [c];
const normalizePath = path => path.startsWith('/') ? path : `/${path}`;

export class CustomRoute {
    /**
     * 构造方法
     * @param {*当前koa的实例} app 
     * @param {*路由的目录} apiPath 
     */
    constructor(app, apiPath) {
        this.app = app;
        this.apiPath = apiPath;
        this.router = new Router;
    }

    /**
     * 初始化所有路由文件
     */
    init () {
        glob.sync(resolve(this.apiPath, '../routes', '**/*.js')).forEach(require);
        for (const [conf, controller] of routerMap) {
            const controllers = isArray(controller);
            const prefixPath = conf.target[symbolPrefix];
            if (prefixPath) {
                prefixPath = normalizePath(prefixPath);
            }
            const routerPath = prefixPath + conf.path;

            this.router[conf.method](routerPath, ...controllers);
        }
        this.app.use(this.router.routes());
        this.app.use(this.router.allowedMethods());
    }
}

// 对路由的装饰
const router = conf => (target, key, descriptor) => {
    console.log(conf);
    conf.path = normalizePath(conf.path);
    routerMap.set({
        target: target,
        ...conf
    }, target[key]);
}

// @controller 控制器实现
export const controller = path => target => (target.prototype[symbolPrefix] = path);

// @get 控制器实现
export const get = path => router({
    method: 'get',
    path: path
})

// @post 控制器实现
export const post = path => router({
    method: 'post',
    path: path
})

// @put 控制器实现
export const put = path => router({
    method: 'put',
    path: path
})

// @del 控制器实现
export const del = path => router({
    method: 'delete',
    path: path
})

// @use 控制器实现
export const use = path => router({
    method: 'use',
    path: path
})

// @all 控制器实现
export const all = path => router({
    method: 'all',
    path: path
})

// const r = new CustomRoute('app', 'xxx/xxx/abc');
// console.log(get)